/* Copyright (c) 2003-2010 Caleb Doise
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;


namespace SharpScraps.Win32
{

    public static class ScreenCapture
    {

        public static Bitmap CaptureCursorRegion(int width, int height)
        {
            Point location = Cursor.Position;

            Bitmap image = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(image))
            {
                int screenLeft = location.X - width / 2;
                int screenTop = location.Y - height / 2;

                g.CopyFromScreen(
                    screenLeft,screenTop,
                    0, 0,
                    new Size(width, height),
                    CopyPixelOperation.SourceCopy);

                Cursor cursor = Cursors.Arrow;
                Rectangle cursorRect = new Rectangle(
                    (location.X - screenLeft),
                    (location.Y - screenTop),
                    cursor.Size.Width,
                    cursor.Size.Height);

                cursor.Draw(g, cursorRect);
            }

            return image;
        }

        public static Bitmap CaptureDesktop()
        {
            return CaptureWindow(USER32.GetDesktopWindow());
        }
        
        public static Bitmap CaptureScreen(Screen screen)
        {
            RECT windowRect = new RECT();
            windowRect.left = screen.WorkingArea.Left;
            windowRect.top = screen.WorkingArea.Top;
            windowRect.right = screen.WorkingArea.Right;
            windowRect.bottom = screen.WorkingArea.Bottom;
       
            Bitmap image = new Bitmap(windowRect.Width, windowRect.Height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(image))
            {
                g.CopyFromScreen(
                    windowRect.left, windowRect.top, 
                    0, 0,
                    new Size(windowRect.Width, windowRect.Height),
                    CopyPixelOperation.SourceCopy);
            }

            return image;
        }

        public static Bitmap CaptureWindow(IntPtr hWnd)
        {
            RECT windowRect;
            USER32.GetWindowRect(hWnd, out windowRect);
            return CaptureWindow(hWnd, windowRect);
        }

        public static Bitmap CaptureWindow(IntPtr hWnd, RECT windowRect)
        {                                              
            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;

            IntPtr hdcSrc = USER32.GetWindowDC(hWnd);
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height); 

            GDI32.SelectObject(hdcDest, hBitmap);

			if (hWnd != USER32.GetDesktopWindow())
			{
				PrintWindow(hWnd, hdcDest, 0);
			}
			else
			{            
				// TODO: Always do the following on pre-WinXP machines.
				GDI32.BitBlt(
					hdcDest,
					0, 0,
					width, height,
					hdcSrc,
					0,0,
					GDI32.SRCCOPY);
			}
             

            Bitmap img = Image.FromHbitmap(hBitmap);                        

            USER32.ReleaseDC(hWnd, hdcSrc);
            GDI32.DeleteDC(hdcDest);
            GDI32.DeleteObject(hBitmap);    
    
            return img;
        }

        
        [DllImport("User32.dll")]
        private extern static bool PrintWindow(
            IntPtr hwnd,     // window to copy
            IntPtr hdcBlt,   // HDC to print into
            UInt32 nFlags    // optional flags (PW_CLIENTONLY for only client)
            );


    } 

}